package idao.engine;

import idao.ConnectionManager;
import idao.DaoRuntimeException;
import idao.IDAO;

import java.sql.SQLException;

import javax.sql.DataSource;

/**
 * @author huhao
 */
public class IDAOImpl implements IDAO
{

    private ConnectionManager cm;
    private DaoProxyBuilder proxyBuilder;

    public IDAOImpl(DataSource ds)
    {
        if (ds == null) {
            throw new NullPointerException("DataSource can not be null!");
        }
        this.cm = new DataSourceConnectionManager(ds);
        this.initProxyBuilder();
    }

    public IDAOImpl(ConnectionManager cm)
    {
        if (cm == null) {
            throw new NullPointerException("ConnectionManager can not be null!");
        }
        this.cm = cm;
        this.initProxyBuilder();
    }

    private void initProxyBuilder()
    {
        try {
            this.proxyBuilder = new JavassistDaoProxy();
        } catch (ClassNotFoundException e) {
            this.proxyBuilder = new JdkDaoProxy();
        }
    }

    public <I> I newDao(Class<? extends I> dao) throws DaoRuntimeException
    {
        return this.proxyBuilder.newDaoProxy(dao, cm);
    }

    public ConnectionManager getConnectionManager()
    {
        return cm;
    }

    public void startTransaction() throws DaoRuntimeException
    {
        TxManager.startTx();
    }

    public void commitTransaction() throws DaoRuntimeException
    {
        TxManager.commitTx();
    }

    public void endTransaction() throws DaoRuntimeException
    {
        try {
            TxManager.endTx();
        } catch (SQLException e) {
            throw new DaoRuntimeException("Failed to end transaction!", e);
        }
    }
}
